#ifndef SDT_H
#define SDT_H
#ifdef __cplusplus
extern "C"
{
#endif

#define DBG_BUILD_SDT 0
/*****************************************************************************
 * Program Map Table
 *****************************************************************************/
static inline ms_u32 sdt_api_buildSection( ms_byte *ptspkt,ms_u08 *cc,ms_u08 pktSize,ms_byte adaption_field_control,
	ms_byte *payload,ms_u32 len_payload,ms_u16 transport_stream_id,ms_u08 sectionIndex,ms_u08 last_section_num)
{
	ms_u16 section_len=len_payload+SI_HEADER_SIZE_SYNTAX1+1;
	ms_byte ptspkt_tmp[5120]={0};
	ms_byte *ptspkt_sdt=mssi_api_setAdaptationFieldLen(adaption_field_control, section_len, ptspkt_tmp,DBG_BUILD_SDT);
	if(ms_null==ptspkt_sdt){
		return 0;
	}
//第一字节填0：1字节			
	ptspkt_sdt[0]=0x00;
	ms_byte *psdt=&ptspkt_sdt[1];
	
//构建SYNTAX1头部：8字节					
	mssi_api_buildSyntax1Head(psdt, SI_TID_SDT_ACT, section_len, transport_stream_id,0,sectionIndex,last_section_num);

	if(DBG_BUILD_SDT)ms_linfo("SDT","len_payload,section_len:%u,%u",len_payload,section_len);
	ms_byte *psdt2=&psdt[SI_HEADER_SIZE_SYNTAX1];
	ms_memcpy(psdt2, payload, len_payload);

//构建CRC：4字节	
	ms_u32 crc=mscrc_api_CRC32(psdt, (section_len-1));
	if(DBG_BUILD_SDT)ms_linfo("SDT","crc:%#x=%u",crc,crc);
	ms_network_4b(&ptspkt_sdt[section_len], crc);

	ms_u08 cc_real=(*cc);
	ms_u16 numTs=(section_len+SI_CRCLEN)/TS_SIZE_PES;
	if((section_len+SI_CRCLEN)%TS_SIZE_PES){
		numTs+=1;
	}
	for(ms_u16 index=0;index<numTs;index++){
		if(!index){
			mssi_api_tsInit(&ptspkt[index*pktSize],SI_PID_SDT,cc_real, pktSize,adaption_field_control,0x01);
		}else{
			mssi_api_tsInit(&ptspkt[index*pktSize],SI_PID_SDT,cc_real, pktSize,0x1,0x00);
		}
		if(++cc_real>0XF){
			cc_real=0;
		}
		ms_byte *src=&ptspkt_tmp[index*TS_SIZE_PES+TS_SIZE_HEADER];
		ms_byte *dst=&ptspkt[index*pktSize+TS_SIZE_HEADER];
		ms_memcpy(dst, src, TS_SIZE_PES);
	}
	(*cc)=cc_real;
	return (numTs*pktSize);
}

static inline ms_u32 sdt_api_buildPayload( ms_byte *data,SDTPARAMContxt *psdt_ctt,ms_u16 original_network_id)
{
	ms_u32 total_len=0;
//构建SYNTAX2头部：3字节 
	ms_byte *psdt2=data;
/*	[15:00]original_network_id*/
	ms_network_2b(&psdt2[0],original_network_id);
/*	[07:00]res_future*/	
	psdt2[2]=0XFF;
	total_len+=3;
//构建节目信息：totalnum*(5+5+len_spn+len_sn)
	for(ms_u32 index=0;index<psdt_ctt->totalnum;index++){
		ms_u08 len_spn=ms_buflen(psdt_ctt->spnList[index])&0xFF;
		ms_u08 len_sn=ms_buflen(psdt_ctt->snList[index])&0xFF;
		ms_byte *psdt_n=&psdt2[total_len];
	//构建ServiceDesLoop1信息：5字节
	/*	[15:00]service_id*/
		ms_network_2b(&psdt_n[0],psdt_ctt->serviceidList[index]);
	/*	[08:02]res_future
		[01:00]EIT_schedule_flag
		[00:00]EIT_present_following_flag*/
		psdt_n[2]=(0x00<<2)&0XFC;
		psdt_n[2]|=(0x00<<1)&0X02;
		psdt_n[2]|=0x00;
	/*	[15:13]running_status
		[12:12]free_CA_mode
		[11:00]des_loop_len*/		
		psdt_n[3]=(0x00<<5)&0XE0;
		psdt_n[3]|=(0x00<<4)&0x10;
		ms_u16 descriptor_loop_len=(SI_SDTLEN_HEADER_ServiceDesLoop2+len_spn+len_sn);
		psdt_n[3]|=(descriptor_loop_len>>8)&0x0F;
		psdt_n[4]=(descriptor_loop_len)&0xFF;

	//构建ServiceDesLoop2信息：（5+len_spn+len_sn）字节
		ms_byte *psdt_dl=&psdt_n[5];
	/*	[07:00]descriptor_tag*/
		psdt_dl[0]=0x48;
	/*	[07:00]descriptor_len*/
		psdt_dl[1]=(0x03+len_sn+len_spn);
	/*	[07:00]service_type*/
		psdt_dl[2]=psdt_ctt->service_type[index];
	/*	[07:00]service_provider_name_len*/
		psdt_dl[3]=len_spn;
	/*	service_provider_name*/	
		ms_memcpy((&psdt_dl[4]), psdt_ctt->spnList[index], len_spn);
	/*	[07:00]service_name_len*/	
		psdt_dl[4+len_spn]=len_sn;
	/*	service_name*/
		ms_memcpy((&psdt_dl[5+len_spn]), psdt_ctt->snList[index], len_sn);
		total_len+=SI_SDTLEN_HEADER_ServiceDesLoop1+SI_SDTLEN_HEADER_ServiceDesLoop2+len_spn+len_sn;
	}
	return total_len;
}	
static inline ms_u32 sdt_api_build( ms_byte *ptspkt,ms_u08 *cc,ms_u08 pktSize,ms_byte adaption_field_control,
	ms_u16 transport_stream_id,ms_u16 original_network_id,SDTPARAMContxt *psdt_ctt)
{
	ms_byte payload[MAX_SECTION*MAX_SECTION_LEN]={0};
/*构建负荷数据*/
	ms_u16 len_payload=sdt_api_buildPayload(payload,psdt_ctt,original_network_id);
	//if(DBG_BUILD_SDT)ms_bufHex("payload", payload, len_payload);
	
/*计算需要传输的section数量*/	
	ms_u08 sectionNum=mssi_api_getSectionNum(len_payload);
	ms_u08 last_section_num=sectionNum-1;

	if(DBG_BUILD_SDT)ms_linfo("SDT","len_payload:%u,sectionNum,last_section_num:%u,%u",
		len_payload,sectionNum,last_section_num);
/*构建完整的TS数据包*/	
	ms_u32 len_build_payload=0;
	ms_u32 len=0;
	for(ms_u08 sectionIndex=0;sectionIndex<sectionNum;sectionIndex++){
		ms_byte *tsBuf=&ptspkt[sectionIndex*pktSize*NUM_TS_MAXSECTION];
		ms_u16 len_payload1=mssi_api_getPayloadLen(len_payload,sectionIndex);
	
		if(DBG_BUILD_SDT)ms_bufHex("payload1", &payload[len_build_payload], len_payload1);
		
		ms_u32 len_build_ts=sdt_api_buildSection(tsBuf,cc,pktSize,adaption_field_control, 
			&payload[len_build_payload],len_payload1,transport_stream_id,sectionIndex,last_section_num);
		
		len_build_payload+=len_payload1;
		len+=len_build_ts;
		//if(DBG_BUILD_SDT)ms_bufHex("ptspkt", tsBuf, len_build_ts);
	}
	//ms_bufHex("ptspkt", ptspkt, len);
	if(DBG_BUILD_SDT)ms_linfo("SDT","len_payload:%u,sectionNum,last_section_num:%u,%u,len:%u",
		len_payload,sectionNum,last_section_num,len);
	
	return len;
}
static inline void sdt_api_build2( ms_byte *ptspkt,ms_u08 cc,ms_u08 pktSize,ms_byte adaption_field_control,ms_u16 service_id,
	ms_string service_provider_name,ms_string service_name,ms_u16 transport_stream_id,ms_u16 original_network_id)
{
	ms_u08 cc_tmp=cc;
	SDTPARAMContxt sdt_ctt;
	ms_memset(&sdt_ctt, 0, ms_bufsize(SDTPARAMContxt));
	sdt_ctt.totalnum=1;
	sdt_ctt.serviceidList[0]=service_id;
	sdt_ctt.service_type[0]=servicetype_digital_tv;
	strcpy(sdt_ctt.spnList[0], service_provider_name);
	strcpy(sdt_ctt.snList[0], service_name);
	sdt_api_build(ptspkt, &cc_tmp, pktSize, adaption_field_control,transport_stream_id,original_network_id, &sdt_ctt);
}

#ifdef __cplusplus
}
#endif

#endif
